home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / MNetsrc.hqx / Mac TCP_IP Source v.33 / mac_path.c < prev    next >
Text File  |  1989-03-10  |  11KB  |  417 lines

  1. /* mac_path.c
  2.  * This module includes the generic path processing code for the KA9Q package, along
  3.  * with the file initialization code (executed only at startup).
  4.  */
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "config.h"
  8. #include "mac_files.h"
  9.  
  10. #include <strings.h>
  11. #include <HFS.h>
  12.  
  13.  
  14. /* pathname
  15.  * Given a working directory and an arbitrary pathname, resolve them into
  16.  * an absolute pathname. Memory is allocated for the result, which
  17.  * the caller must free.
  18.  *
  19.  * path is prefixed by a colon:
  20.  *        cd:path is returned (leading colon from path provides the cd separator)
  21.  * path is NOT prefixed by a colon, but path contains a colon:
  22.  *        path is returned
  23.  * path does not contain a colon:
  24.  *        cd:path is returned (colon separator is generated)
  25.  *
  26.  *    The final absolute path is examined for ::; each such occurrence will "backup"
  27.  *    the path past the previous folder.
  28.  */
  29.  
  30. char *
  31. pathname(cd,path)
  32. char *cd;    /* Current working directory */
  33. char *path;    /* Pathname argument */
  34. {
  35.     int stcpm();
  36.     register char *buf;
  37.     register char *ptr;
  38.     char *dcolon();
  39.     char * ptr2;
  40.     int colon;
  41.         
  42. /* Ignore blank args and strip any leading white space on args
  43.  * note: send empty strings, not null pointers for a "blank" arg)
  44.  */
  45.  
  46.     if (cd == NULLCHAR || path == NULLCHAR)
  47.         return(NULLCHAR);
  48.     while (*cd == ' ' || *cd == '\t')
  49.         cd++;
  50.     while (*path == ' ' || *path == '\t')
  51.         path++;
  52.  
  53. /* Allocate and initialize output buffer; user must free */
  54.     
  55.     if ((buf = malloc(strlen(cd) + strlen(path)+2)) == NULLCHAR) {
  56.         printf("pathname:  could not allocate memory.\n");
  57.         return(NULLCHAR);
  58.     }
  59.  
  60. /* OK, we have:
  61.     cd        contains the working directory from our caller
  62.     path    contains the pathname to be used in the context of the above
  63.     
  64. Now we must earn our keep and resolve the above three to come out with
  65. an absolute path name. Somebody else will actually check it to insure that
  66. access is allowed. */
  67.  
  68.     if ((colon = strpos(path,PATH_DELIM)) == 0) {
  69.  
  70.     /* interpret path relative to cd, path IS prefixed */
  71.         if (strlen(cd)) {                    /* if we have a cd */
  72.             sprintf(buf,"%s",cd);            /* get cd in buf first */
  73.             if (buf[strlen(buf)-1] == PATH_DELIM)
  74.                 buf[strlen(buf)-1]=NULL;    /* drop last character */
  75.             sprintf(buf,"%s%s",buf,path);    /* use cd followed by path */
  76.         }
  77.         else {
  78.             ptr = path;                        /* drop prefix in path */
  79.             ptr++;
  80.             sprintf(buf,"%s",ptr);            /* use path less prefix*/
  81.         }
  82.     }
  83.     else {
  84.  
  85.     /* interpret path relative to cd, path is NOT prefixed */
  86.         if (strlen(cd) && (colon ==-1)) {    /* if we have a cd  and no other colons */
  87.             sprintf(buf,"%s",cd);            /* get cd in buf first */
  88.             if (buf[strlen(buf)-1] == PATH_DELIM)
  89.                 buf[strlen(buf)-1]=NULL;    /* drop last character */
  90.             sprintf(buf,"%s:%s",buf,path);    /* use cd followed by path */
  91.         }
  92.         else
  93.             sprintf(buf,"%s",path);            /* use path as-is */
  94.     }    
  95.     
  96. /* Special case: null final path means the application root directory */
  97.  
  98.     if (buf[0] == NULL)
  99.         sprintf(buf,"%s",applroot);    
  100.  
  101. /* now, examine what we are about to return to process double colons */
  102.  
  103.     if ((ptr2 = dcolon(buf)) != NULLCHAR) {
  104.         *ptr2 = NULL;                /* early-terminate buf */
  105.         ptr2++;                    /* ptr2 is the second part of buf, includes 1 colon */
  106.         if ((ptr = rindex(buf,PATH_DELIM)) == NULLCHAR)
  107.             strcpy(buf,ptr2);
  108.         else
  109.             strcpy(ptr,ptr2);        /* copy part after ptr2 to replace last colon */
  110.     }
  111.     return(buf);
  112. }
  113.  
  114. /* find_dcolon
  115.  *    search a string for the first occurrence of a double colon.
  116.  */
  117.  
  118. char *
  119. dcolon(string)
  120. char *string;
  121.  
  122. {
  123.     char *colon,*ptr;
  124.     
  125.     if (string == NULLCHAR)            /* can't work without data */
  126.         return(NULLCHAR);
  127.  
  128.     ptr = string;
  129.     while ((colon = index(ptr,PATH_DELIM)) != NULLCHAR) {
  130.         colon++;
  131.         if (*colon == NULL)
  132.             return(NULLCHAR);
  133.         if (*colon == PATH_DELIM) {
  134.             colon--;
  135.             return(colon);
  136.         }
  137.         ptr = colon;
  138.     }
  139.     /* no double colon seen, so exit */
  140.     return(NULLCHAR);
  141. }
  142.         
  143. /* mac_files
  144.  * Handle the one-time initialization needed for the Macintosh file names.
  145.  * Entry with flag == 1 will remove any SMTPxxxx files from the application root,
  146.  * and any .LCK files in the mail queue directory.
  147.  * Entry with flag == 0 will not remove any preexisting files.
  148.  *  (NET uses flag==1, BM uses flag==0)
  149.  */
  150.  
  151. int
  152. mac_files(flag)
  153. int flag;
  154. {
  155.     int MyVRefNum, e;
  156.     int len;
  157.     char buf[256],delname[256];
  158.     char *cp,*GetPathname(),*GetVolumename();
  159.     FILE *fp,*dir();
  160.     
  161. /*
  162.  * Get the path to the folder where we started NET and save in applroot
  163.  * (since we are called shortly after application launch, the default working
  164.  * directory is still set to the folder from which the application was launched).
  165.  */
  166.     GetVolumename(NULL,&MyVRefNum);        /* get default volume reference number */
  167.     GetPathname(applroot,MyVRefNum);    /* get default path name */
  168.  
  169. /* have basic path info, now generate the derivative path names */
  170.     
  171.     check_len(STARTUP);
  172.     sprintf(startup,"%s%s", applroot, STARTUP);
  173.  
  174.     check_len(USERFILE);
  175.     sprintf(userfile,"%s%s", applroot, USERFILE);
  176.  
  177.     check_len(HOSTS);
  178.     sprintf(hosts,"%s%s", applroot, HOSTS);
  179.  
  180.     check_len(MAILSPOOL);
  181.     sprintf(mailspool,"%s%s", applroot, MAILSPOOL);
  182.  
  183.     check_len(MAILQDIR);
  184.     sprintf(mailqdir,"%s%s", applroot, MAILQDIR);
  185.  
  186.     check_len(MAILQUEUE);
  187.     sprintf(mailqueue,"%s%s", applroot, MAILQUEUE);
  188.  
  189.     check_len(BMRC);
  190.     sprintf(bmrc,"%s%s", applroot, BMRC);
  191.  
  192.     check_len(ROUTEQDIR);
  193.     sprintf(routeqdir,"%s%s", applroot, ROUTEQDIR);
  194.  
  195.     check_len(ALIAS);
  196.     sprintf(alias,"%s%s", applroot, ALIAS);
  197.  
  198.     check_len(FINGERPATH);
  199.     sprintf(fingerpath,"%s%s", applroot, FINGERPATH);
  200.  
  201.     check_len(TEMPPATH);
  202.     sprintf(temppath,"%s%s", applroot, TEMPPATH);
  203.  
  204.     check_len(DIRNET);
  205.     sprintf(dirnet,"%s%s", applroot, DIRNET);
  206.  
  207.     strcpy(logname,applroot);
  208. #ifdef CALLBK
  209.     strcpy(callbook,applroot);
  210.     strcpy(calllog,applroot);
  211. #endif
  212.     
  213. /*
  214.  * all the fixed locations have been written, now run through some of the folders
  215.  * looking for left-over files that we will delete before real startup.
  216.  */
  217.     if (flag == 0)
  218.         return(0);        /* first see if we are supposed to delete files */
  219.         
  220.     /* start with .lck files in the mail queue folder */
  221.     
  222.     fp = dir(mailqdir,0);                        /* delete all .lck files */
  223.     if ( fp == NULLFILE)    /* Check for existence of mail folder */    
  224.     {
  225.         printf("mac_path: could not find mail folder.\n");
  226.         exit(-1);    
  227.     }
  228.      while (fgets(buf,sizeof(buf),fp),!feof(fp)) {
  229.         if ((cp = index(buf,'\n')) == NULLCHAR)
  230.             continue;
  231.         *cp = NULL;        /* set to null string */
  232.         if ((cp = index(buf,'.')) != 0) {
  233.             cp++;
  234.             if (strncmp(cp,"lck",3) == 0) {
  235.                 sprintf(delname,"%s%c%s",mailqdir,PATH_DELIM,buf);
  236.                 unlink(delname);
  237.                 continue;        /* Delete lock file */
  238.             }
  239.         }
  240.     }
  241.     if (feof(fp)) {
  242.         /* have deleted any .lck files, now close and continue */
  243.         fclose(fp);
  244.         unlink(dirnet);        /* delete the dirnet.temp file */
  245.     }
  246.     
  247.     /* look for SMTPxxxxx files in the application root folder */
  248.  
  249.     fp = dir(temppath,0);                        /* delete all SMTP files */
  250.     if ( fp == NULLFILE)    /* Check for existence of applroot */    
  251.     {
  252.         printf("mac_path: could not find application folder.\n");
  253.         exit(-1);    
  254.     }
  255.      while (fgets(buf,sizeof(buf),fp),!feof(fp)){
  256.         if ((cp = index(buf,'\n')) == NULLCHAR)
  257.             continue;
  258.         *cp = NULL;        /* set to null string */
  259.         if ((cp = index(buf,'S')) != 0) {
  260.             if (strncmp(cp,"SMTP",4) == 0) {
  261.                 sprintf(delname,"%s%s",temppath,buf);
  262.                 unlink(delname);
  263.                 continue;            /* Delete SMTP files */
  264.             }
  265.         }
  266.     }
  267.     if (feof(fp)) {
  268.         /* have deleted any SMTP files, now close and continue */
  269.         fclose(fp);
  270.         unlink(dirnet);        /* delete the dirnet.temp file */
  271.     }
  272.     return(0);
  273. }
  274.  
  275. /* check_len
  276.  * handle length checking for our path names in a rather specialized manner.
  277.  */
  278.  
  279. check_len(str)
  280. char *str;
  281. {
  282.     if ( (strlen(applroot) + strlen(str)) > 255 ) {
  283.         printf("Pathname to %s (max is 255) is to long, please shorten the path.\n", str);
  284.         printf("The pathname you attempted was %s%s\n", applroot, str);
  285.         exit(1);
  286.     }
  287. }
  288.  
  289. /* GetPathname
  290.  *
  291.  * This routine is passed either a working directory reference number or a volume
  292.  * reference number, and a pointer to a string. For a WDRefNum, the full path of
  293.  * the directory is returned (with trailing colon). For a VRefNum, the name of the
  294.  * volume or of the default working directory on that volume will be returned
  295.  * (with a trailing colon).
  296.  *
  297.  * Note that the string must be able to handle storage of up to 255 characters.
  298.  *
  299.  * modified from Mike Schuster, "Programming for HFS Compatibility ", 
  300.  * The Complete MacTutor, Vol. 2, pg. 87.
  301.  *
  302.  * (Mac C) to Light Speed C translation by Jeff Meredith 12/88
  303.  *
  304.  * additional documentation Edwin (Ned) Kroeker, N1EWB, 1/89
  305.  *
  306.  * Changes. 
  307.  * 1. removed requirement to pass size of wdrefnum(sizeof(wdrefnum)) as the
  308.  *    third parameter.
  309.  * 2. removed need for strntac() which is not in LSC libraries.
  310.  * 3. minor typecasting changes to match LSC prototypes.
  311.  * 4. FSFCBLen defined in HFS.h, no need to define here. If we detect MFS only,
  312.  *    we'll handle (FSFCBLen == -1 for MFS, == length of fcb for HFS)
  313.  * 5. All paths now return a trailing colon rather than no colon.
  314.  */
  315.  
  316. #define mfsSigWord 0xd2d7
  317. #define hfsSigWord 0x4244
  318. #define rootDirID 2
  319.  
  320. char *GetPathname(pname,wdrefnum)
  321. char *pname;
  322. int wdrefnum;
  323. {
  324.     HVolumeParam vp;
  325.     WDPBRec wp;
  326.     DirInfo dp;
  327.     char dname[256];
  328.     char *strtac(),*cp;
  329.  
  330. /* initialize parameters */
  331.     pname[0] = NULL;
  332.  
  333.     vp.ioNamePtr=(StringPtr)&dname;
  334.     vp.ioVRefNum=wdrefnum;
  335.     vp.ioVolIndex=0;
  336.     wp.ioNamePtr=0L;
  337.     wp.ioVRefNum=wdrefnum;
  338.     wp.ioWDIndex=0;
  339.     wp.ioWDProcID=0L;
  340.     dp.ioNamePtr=(StringPtr)&dname;
  341.     dp.ioFDirIndex=-1;
  342.  
  343. /* get volume information */
  344.  
  345.     if(!PBHGetVInfo(&vp,0))
  346.     /*
  347.      * if MFS or HFS root, return volume name only
  348.      */
  349.         if(FSFCBLen==-1||vp.ioVSigWord==mfsSigWord||vp.ioVRefNum==wdrefnum) {
  350.             strcat(pname,PtoCstr((Ptr)vp.ioNamePtr));
  351.             strcat(pname,":");
  352.         }
  353.  
  354. /* get working directory information */
  355.  
  356.     else if (!PBGetWDInfo(&wp,0)) {
  357.     
  358.     /* traverse path from working directory to root */
  359.         dp.ioVRefNum=wp.ioWDVRefNum;
  360.         dp.ioDrParID=wp.ioWDDirID;
  361.         do
  362.        {
  363.            /* get next node information */
  364.             dp.ioDrDirID=dp.ioDrParID;
  365.             if(PBGetCatInfo(&dp,0))
  366.                 break;
  367.                 
  368.             /*concatenate node name to result*/
  369.             strtac(pname,":");
  370.             strtac(pname,PtoCstr((Ptr)dp.ioNamePtr));
  371.         }
  372.         while(dp.ioDrDirID!=rootDirID);
  373.     }
  374.     /* Translate entire buffer to lower case (we do comparisons later) */
  375.     for(cp = pname;*cp != '\0';cp++)
  376.         *cp = tolower(*cp);
  377.     return(pname);
  378. }
  379.  
  380. /* GetVolumename
  381.  * This routine returns the volume name and reference number of the current default
  382.  * volume. This routine will function on both MFS and HFS systems. The string passed
  383.  * must be able to handle up to the maximum 255 character limit. If a null pointer
  384.  * is passed instead of the string, only the volume reference number is returned.
  385.  */
  386.  
  387.  char *GetVolumename(vname,vrefnum)
  388.  char *vname;
  389.  int *vrefnum;
  390.  {
  391.      WDPBRec DefDisk;
  392.      char *cp;
  393.      
  394. /* initialize parameters */
  395.      
  396.      if (vname == NULLCHAR)
  397.          DefDisk.ioNamePtr = NULL;
  398.      else
  399.          DefDisk.ioNamePtr = (StringPtr) vname;
  400.      
  401.      if ( (PBHGetVol(&DefDisk,FALSE) ) != 0) {
  402.         printf("Could not get the volume path name.\n");
  403.         exit(-1);    
  404.     }
  405.  
  406.     *vrefnum = DefDisk.ioVRefNum;        /* copy the volume reference number */
  407.     if (DefDisk.ioNamePtr != NULL) {
  408.         PtoCstr(vname);                    /* convert name string to C */
  409.     /* Translate entire buffer to lower case (we do comparisons later) */
  410.         for(cp = vname;*cp != '\0';cp++)
  411.             *cp = tolower(*cp);
  412.         return(vname);
  413.     }
  414.     else
  415.         return (NULLCHAR);
  416. }
  417.